/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using WinForms.Renderer;
using DirectShowLib;
using Microsoft.DirectX.Direct3D;
using DirectShowLib.Sample;
using Core.Model.Ingredients.Presentable.Visibles;
using Bitmap=System.Drawing.Bitmap;

namespace WinForms
{
    public partial class Screen :Form
    {

        public delegate void refreshDelegate ( System.Drawing.Rectangle [] rs, List<Visible> vs );

        MHEGScreen mhegscreen;
        public Bitmap bitmap = new Bitmap(MHEGDisplayConstants.DefaultMHEGPanelSize.Width,MHEGDisplayConstants.DefaultMHEGPanelSize.Height,System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        
        public Screen ()
        {
            InitializeComponent();
            this.SetStyle( ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint, true );
            mhegscreen = new MHEGScreen( MHEGRenderMode.GDIPlusBitmap );

            this.Size = new Size( MHEGDisplayConstants.DefaultMHEGPanelSize.Width, MHEGDisplayConstants.DefaultMHEGPanelSize.Height );
                       
            mhegscreen.Clear( bitmap);

            
        }


        public  void Clear ()
        {
            mhegscreen.Clear( bitmap );
            DisplayControl.Instance.Mix( bitmap );
        }


        private void Screen_FormClosing ( object sender, FormClosingEventArgs e )
        {
            DisplayControl.Instance.Remote.TurnTVOFF();
        }

        public void CleanUp ()
        {
            bitmap.Dispose();
        }


        public  void Refresh ( System.Drawing.Rectangle [] rs ,List<Core.Model.Ingredients.Presentable.Visibles.Visible> vs )
        {
                if ( mhegscreen != null )
                {

                    if ( this.InvokeRequired )
                    {
                        this.BeginInvoke( new refreshDelegate( this.Refresh ), new object [] { rs ,vs} );
                        return;
                    }
                    
 
                    bitmap = mhegscreen.Refresh( rs,vs,bitmap );

                    DisplayControl.Instance.Mix( bitmap );
                }
                
        }

        private void Screen_Resize ( object sender, EventArgs e )
        {
            //toolTip1.SetToolTip( screen.Panel, this.Size.ToString() );

            DisplayControl.Instance.MoveVideoWindow( this.ClientRectangle );
        }

        private void Screen_Move ( object sender, EventArgs e )
        {
            DisplayControl.Instance.MoveVideoWindow( this.ClientRectangle );
        }

        private void Screen_Paint ( object sender, PaintEventArgs e )
        {
            if ( DisplayControl.Instance.windowlessCtrl != null )
            {
                IntPtr hdc = e.Graphics.GetHdc();
                int hr = DisplayControl.Instance.windowlessCtrl.RepaintVideo( this.Handle, hdc );
                e.Graphics.ReleaseHdc( hdc );
            }
        }

        private void HandleGraphEvent ()
        {
            int hr = 0;
            EventCode evCode;
            System.IntPtr evParam1, evParam2;

            // Make sure that we don't access the media event interface
            // after it has already been released.
            if ( DisplayControl.Instance.mediaEventEx == null )
                return;

            // Process all queued events
            while ( DisplayControl.Instance.mediaEventEx.GetEvent( out evCode, out evParam1, out evParam2, 0 ) == 0 )
            {
                // Free memory associated with callback, since we're not using it
                hr = DisplayControl.Instance.mediaEventEx.FreeEventParams( evCode, evParam1, evParam2 );

                //// If this is the end of the clip, reset to beginning
                //if ( evCode == EventCode.Complete )
                //{
                //    DsLong pos = new DsLong( 0 );
                //    // Reset to first frame of movie
                //    hr = this.mediaSeeking.SetPositions( pos, AMSeekingSeekingFlags.AbsolutePositioning,
                //      null, AMSeekingSeekingFlags.NoPositioning );
                //    if ( hr < 0 )
                //    {
                //        // Some custom filters (like the Windows CE MIDI filter)
                //        // may not implement seeking interfaces (IMediaSeeking)
                //        // to allow seeking to the start.  In that case, just stop
                //        // and restart for the same effect.  This should not be
                //        // necessary in most cases.
                //        hr = this.mediaControl.Stop();
                //        hr = this.mediaControl.Run();
                //    }
                //}
            }
        }

        private const int WMGraphNotify = 0x0400 + 13;

        protected override void WndProc ( ref Message m )
        {
            switch ( m.Msg )
            {
                case WMGraphNotify:
                    {
                        HandleGraphEvent();
                        break;
                    }
            }

            //// Pass this message to the video window for notification of system changes
            //if ( this.videoWindow != null )
            //    this.videoWindow.NotifyOwnerMessage( m.HWnd, m.Msg, m.WParam.ToInt32(), m.LParam.ToInt32() );

            base.WndProc( ref m );
        }

        private void Screen_KeyDown ( object sender, KeyEventArgs e )
        {
            DisplayControl.Instance.Remote.DoKey( e );
        }
        
    }
}